package com.shiguiwu.springboot3.service;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.json.JSONUtil;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.shiguiwu.springboot3.dto.UserDTO;
import com.shiguiwu.springboot3.feign.UserFeignApi;
import com.shiguiwu.springboot3.mapper.OrderMapper;
import com.shiguiwu.springboot3.util.R;
import io.github.resilience4j.circuitbreaker.annotation.CircuitBreaker;
import io.github.resilience4j.ratelimiter.annotation.RateLimiter;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets;

/**
 * @description: 订单service
 * @author: stone
 * @date: Created by 2023/7/3 12:08
 * @version: 1.0.0
 * @pakeage: com.shiguiwu.springboot3.service
 */
@Service
@Slf4j
public class OrderService {

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private UserFeignApi userFeignApi;

    public Integer test() {
        return orderMapper.queryTest();
    }

    @GlobalTransactional(rollbackFor = Exception.class)
    @Transactional(rollbackFor = Exception.class)
    public Integer test2() {

        //int i = orderMapper.saveUser(RandomUtil.randomInt(), new Date());
        String s = userFeignApi.testBatch();
        return 1;
    }

    @CircuitBreaker(name = "tools", fallbackMethod = "fallback")
    @RateLimiter(name = "tools")
    public Integer test3() {
        Integer i = userFeignApi.test3();
        String s = JSONUtil.toJsonStr(i);
        log.info("包装类转json ==> {}", s);
        log.info("包装类转json1 ==> {}", JSONUtil.toJsonStr(true));
        log.info("包装类转json ==> {}", JSONUtil.toJsonStr(6.777));
        return i;
    }

    public Integer fallback(Throwable t) {


        // Your fallback code here
        log.error("出异常了===> {}", t.getMessage());
        return -1;
    }

    public R<UserDTO> test4() {
        UserDTO userDTOR = userFeignApi.test4();
        return R.ok(userDTOR);
    }


    public R<UserDTO> test5() {
        UserDTO userDTOR = userFeignApi.test5();
        R<UserDTO> userDTOR1 = userFeignApi.test6();
        return R.ok(userDTOR);
    }

    public static void main(String[] args) throws IOException, NoSuchMethodException {
        R<Integer> ok = R.ok(1);
        String jsonStr = JSONUtil.toJsonStr(ok);


        R r = JSONUtil.toBean(jsonStr, R.class);

        Object getData = ReflectUtil.invoke(r, "getData");
        //转化器使用
        Integer convert = Convert.convert(Integer.class, getData);
        log.error("结果 ===> {}", convert);

        ObjectMapper objectMapper = new ObjectMapper();

        R r1 = objectMapper.readValue(jsonStr, R.class);
        R r2 = objectMapper.readValue(jsonStr.getBytes(StandardCharsets.UTF_8), R.class);

        log.error("结果1 ===> {}", r1);
        log.error("结果2 ===> {}", r2);

        UserDTO userDTO = new UserDTO();
        userDTO.setUsername("aaa");
        userDTO.setId(1);
        R<UserDTO> ok1 = R.ok(userDTO);

        String jsonStr1 = JSONUtil.toJsonStr(ok1);
        Type type = null;
        Method getData1 = OrderService.class.getMethod("test4");
        Type genericReturnType = getData1.getGenericReturnType();
        R<UserDTO> r3 = objectMapper.readValue(jsonStr1, new TypeReference<R<UserDTO>>() {
        });
        R r4 = objectMapper.readValue(jsonStr1.getBytes(StandardCharsets.UTF_8), objectMapper.constructType(genericReturnType));

        log.error("结果1 ===> {}", r3);
        log.error("结果2 ===> {}", r4);

        Object data = r.getData();
        Object r5 = objectMapper.readValue(r4.getData().toString(), new TypeReference<Integer>() {
        });

        log.error("结果4 ===> {}", r5);

    }

    public R<UserDTO> timeout(long time) {
        return userFeignApi.timeout(time);
    }

    public R<Integer> ex(long time) {
        return userFeignApi.ex(time);
    }
}
